v0.4.14 — surface source_excerpt + meeting_date in read responses#21
Conversation
The "tie meeting context to code" value prop only worked at write
time. At read time, brief / drift / search returned the decision
text and source_ref string but stripped the raw source passage that
produced the decision — even though source_span.text was sitting in
the ledger waiting to be surfaced. Surfaced during demo gallery work
when the visual was forced to either invent meeting context or look
thin.
Added:
- DecisionMatch.source_excerpt + meeting_date (search responses)
- DriftEntry.source_excerpt + meeting_date (drift responses)
- BriefDecision.source_excerpt + meeting_date (brief responses)
- search_by_bm25 pulls source_span.{text, meeting_date} via
<-yields<-source_span reverse traversal in the same query — no
extra DB roundtrip
- get_decisions_for_file does a single follow-up batched query
against matched intent IDs to backfill the same fields
- Synthetic-span filter: _reground_ungrounded writes placeholder
source_spans where text == intent.description to trigger lazy
grounding. Both query paths filter those out so the excerpt
reflects the original meeting passage, never the bookkeeping
placeholder.
Tests:
- 4 new cases in tests/test_v0414_source_excerpt.py covering
search/brief/drift/empty paths
- Test isolation fixes for v0.4.13 dedup tests that were sharing
state with v0.4.14 tests via the in-memory ledger singleton
Full v0.4.14 regression: 215 passed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThe changes add Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
v1 → v2: F-1 (BLOCKING razor) closed via Phase 0a decomposition. F-2 (NON-BLOCKING OWASP A01/A05) and F-3 (truncation semantics) also closed in same amendment. Plan content hash: sha256:4b25a8f9... Audit report hash: sha256:2bc161d2... Chain hash: 86225d4919f2335322b43bfff8e8d9b63fb4bcd768f0c4ae90751dbcbabb1fd7 Next: /qor-implement.
…hook
Phase 0a — Decompose server.py:cli_main (92 LOC → 15 LOC orchestrator
+ _register_subparsers (16 LOC) + _dispatch (29 LOC)). Razor-compliant.
Phase 0 — Promote cli/branch_scan.py:_invoke_link_commit to shared
cli/_link_commit_runner.py module. Pure refactor under existing
test_branch_scan_cli.py coverage.
Phase 1 — Register link_commit CLI subcommand:
- cli/link_commit_cli.py (29 LOC) — JSON-to-stdout default, --quiet
flag, always exits 0 (graceful skip on no-ledger or handler error).
- server.py — subparser registration in _register_subparsers + dispatch
branch in _dispatch.
- tests/test_link_commit_cli.py (6 tests) — argparse defaults, output
shape, --quiet, no-ledger graceful skip, handler-exception graceful
skip.
Phase 2 — Harden post-commit hook:
- setup_wizard.py:_GIT_POST_COMMIT_HOOK now writes stderr to
${HOME}/.bicameral/hook-errors.log (was /dev/null), surfaces a
one-line summary on stderr, always exits 0. > truncates the file
on each run so successful commits auto-clear stale errors. F-2
remediation per audit v2.
- tests/test_hook_command_registration.py (3 tests) — smoke that
walks every bicameral-mcp <cmd> in installed hooks and asserts
CLI registration + dispatch coverage. Original #124 bug class is
now caught at PR time.
Phase 3 — CHANGELOG [Unreleased] Fixed entry.
Validation: 20 passed, 1 skipped (Windows chmod). ruff check + format
+ mypy clean. Manual smoke: link_commit --help renders.
Plan v2 PASS at META_LEDGER #21 (chain 86225d49). Implementation
sealed at META_LEDGER #22 (chain e83d674c).
Closes #124.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reality matches Promise. All 8 files (5 new + 4 modified - 1 plan) land per v2 plan; 9 new tests + 11 regression = 20 passed, 1 skipped; ruff/format/mypy clean; manual smoke confirms link_commit subcommand registers and renders correctly. Plan: plan-124-post-commit-hook-fix.md (v2 PASS @ 44c6568) Audit: META_LEDGER #21 (chain hash 86225d49) Implementation: META_LEDGER #22 (chain hash e83d674c) Merkle seal: 950f362cb700da5a4db85c545f6b55bb725502a5744bfbb2c2eb3a9c9728661a Closes #124 silent-failure regression. Defense-in-depth: the fix itself, the cli_main decomposition (so the next subcommand addition doesn't hit the same wall), the hook-command-registration smoke test (catches this bug class at PR time), and the loud-but-non-blocking hook (next regression surfaces immediately). Capability shortfalls: gate artifacts, reliability sweep, version bump all skipped (qor/ runtime helpers absent on this branch). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…hook
Phase 0a — Decompose server.py:cli_main (92 LOC → 15 LOC orchestrator
+ _register_subparsers (16 LOC) + _dispatch (29 LOC)). Razor-compliant.
Phase 0 — Promote cli/branch_scan.py:_invoke_link_commit to shared
cli/_link_commit_runner.py module. Pure refactor under existing
test_branch_scan_cli.py coverage.
Phase 1 — Register link_commit CLI subcommand:
- cli/link_commit_cli.py (29 LOC) — JSON-to-stdout default, --quiet
flag, always exits 0 (graceful skip on no-ledger or handler error).
- server.py — subparser registration in _register_subparsers + dispatch
branch in _dispatch.
- tests/test_link_commit_cli.py (6 tests) — argparse defaults, output
shape, --quiet, no-ledger graceful skip, handler-exception graceful
skip.
Phase 2 — Harden post-commit hook:
- setup_wizard.py:_GIT_POST_COMMIT_HOOK now writes stderr to
${HOME}/.bicameral/hook-errors.log (was /dev/null), surfaces a
one-line summary on stderr, always exits 0. > truncates the file
on each run so successful commits auto-clear stale errors. F-2
remediation per audit v2.
- tests/test_hook_command_registration.py (3 tests) — smoke that
walks every bicameral-mcp <cmd> in installed hooks and asserts
CLI registration + dispatch coverage. Original #124 bug class is
now caught at PR time.
Phase 3 — CHANGELOG [Unreleased] Fixed entry.
Validation: 20 passed, 1 skipped (Windows chmod). ruff check + format
+ mypy clean. Manual smoke: link_commit --help renders.
Plan v2 PASS at META_LEDGER #21 (chain 86225d49). Implementation
sealed at META_LEDGER #22 (chain e83d674c).
Closes #124.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 431e202)
Adaptation: server.py — kept dev's _register_subparsers / _dispatch helper extraction (#124 phase 0a refactor) so test_hook_command_registration.py introspection works; omitted dev's branch-scan subparser registration and the setup --with-push-hook flag (both are #48 prerequisites missing on triage)
Adaptation: server.py:_dispatch — kept dev's setup → branch-scan → link_commit dispatch chain shape; dropped branch-scan dispatch case (cli/branch_scan.py is a missing prerequisite from #48 on triage); kept link_commit dispatch case (the actual #124 fix)
Adaptation: tests/test_hook_command_registration.py — dropped _GIT_PRE_PUSH_HOOK import + the test_pre_push_hook_command_is_registered test (pre-push hook is from #48, not on triage); test_all_hook_commands_have_dispatch_branches scoped to _GIT_POST_COMMIT_HOOK only; test_post_commit_hook_command_is_registered (the canonical #124 regression test) is preserved
Skip: cli/branch_scan.py — kept triage's prior absence of this file (added by #48); the cherry-pick wanted to refactor it
Skip: docs/META_LEDGER.md — kept triage's HEAD chain state; e6d4b8f's META_LEDGER #21/#23 entries are dev's chain, not triage's
Skip: CHANGELOG.md — kept triage's HEAD; v0.X.Y triage release narrative goes in PR #128 per DEV_CYCLE §10.5.4
…hook
Phase 0a — Decompose server.py:cli_main (92 LOC → 15 LOC orchestrator
+ _register_subparsers (16 LOC) + _dispatch (29 LOC)). Razor-compliant.
Phase 0 — Promote cli/branch_scan.py:_invoke_link_commit to shared
cli/_link_commit_runner.py module. Pure refactor under existing
test_branch_scan_cli.py coverage.
Phase 1 — Register link_commit CLI subcommand:
- cli/link_commit_cli.py (29 LOC) — JSON-to-stdout default, --quiet
flag, always exits 0 (graceful skip on no-ledger or handler error).
- server.py — subparser registration in _register_subparsers + dispatch
branch in _dispatch.
- tests/test_link_commit_cli.py (6 tests) — argparse defaults, output
shape, --quiet, no-ledger graceful skip, handler-exception graceful
skip.
Phase 2 — Harden post-commit hook:
- setup_wizard.py:_GIT_POST_COMMIT_HOOK now writes stderr to
${HOME}/.bicameral/hook-errors.log (was /dev/null), surfaces a
one-line summary on stderr, always exits 0. > truncates the file
on each run so successful commits auto-clear stale errors. F-2
remediation per audit v2.
- tests/test_hook_command_registration.py (3 tests) — smoke that
walks every bicameral-mcp <cmd> in installed hooks and asserts
CLI registration + dispatch coverage. Original #124 bug class is
now caught at PR time.
Phase 3 — CHANGELOG [Unreleased] Fixed entry.
Validation: 20 passed, 1 skipped (Windows chmod). ruff check + format
+ mypy clean. Manual smoke: link_commit --help renders.
Plan v2 PASS at META_LEDGER #21 (chain 86225d49). Implementation
sealed at META_LEDGER #22 (chain e83d674c).
Closes #124.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 431e202)
Adaptation: server.py — kept dev's _register_subparsers / _dispatch helper extraction (#124 phase 0a refactor) so test_hook_command_registration.py introspection works; omitted dev's branch-scan subparser registration and the setup --with-push-hook flag (both are #48 prerequisites missing on triage)
Adaptation: server.py:_dispatch — kept dev's setup → branch-scan → link_commit dispatch chain shape; dropped branch-scan dispatch case (cli/branch_scan.py is a missing prerequisite from #48 on triage); kept link_commit dispatch case (the actual #124 fix)
Adaptation: tests/test_hook_command_registration.py — dropped _GIT_PRE_PUSH_HOOK import + the test_pre_push_hook_command_is_registered test (pre-push hook is from #48, not on triage); test_all_hook_commands_have_dispatch_branches scoped to _GIT_POST_COMMIT_HOOK only; test_post_commit_hook_command_is_registered (the canonical #124 regression test) is preserved
Skip: cli/branch_scan.py — kept triage's prior absence of this file (added by #48); the cherry-pick wanted to refactor it
Skip: docs/META_LEDGER.md — kept triage's HEAD chain state; e6d4b8f's META_LEDGER #21/#23 entries are dev's chain, not triage's
Skip: CHANGELOG.md — kept triage's HEAD; v0.X.Y triage release narrative goes in PR #128 per DEV_CYCLE §10.5.4
Summary
The "tie meeting context to code" value prop only worked at write time. At read time, brief / drift / search returned the decision text and the source_ref string but stripped the raw source passage — even though `source_span.text` was sitting in the ledger waiting to be surfaced. Surfaced during demo gallery work when the visual was forced to either invent context or look thin.
Changes
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
source_excerptandmeeting_datefields to decision responses in search results, briefs, and drift detection, providing richer context for each decision match.Tests
Chores